home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / msdos / msdos.c < prev    next >
C/C++ Source or Header  |  2000-05-20  |  10KB  |  377 lines

  1. /***************************************************************************
  2.  
  3.   osdepend.c
  4.  
  5.   OS dependant stuff (display handling, keyboard scan...)
  6.   This is the only file which should me modified in order to port the
  7.   emulator to a different system.
  8.  
  9. ***************************************************************************/
  10.  
  11. #include "mamalleg.h"
  12. #include "driver.h"
  13. #include <dos.h>
  14. #include <signal.h>
  15. #include <time.h>
  16. #include <ctype.h>
  17. #include "ticker.h"
  18.  
  19. #ifdef MESS
  20. #include "mess/msdos.h"
  21. /* from msdos/config.c */
  22. extern char *crcdir;
  23. static char crcfilename[256] = "";
  24. const char *crcfile = crcfilename;
  25. extern char *pcrcdir;
  26. static char pcrcfilename[256] = "";
  27. const char *pcrcfile = pcrcfilename;
  28. #endif
  29.  
  30.  
  31. int  msdos_init_seal (void);
  32. int  msdos_init_sound(void);
  33. void msdos_init_input(void);
  34. void msdos_shutdown_sound(void);
  35. void msdos_shutdown_input(void);
  36. int  frontend_help (int argc, char **argv);
  37. void parse_cmdline (int argc, char **argv, int game);
  38. void init_inpdir(void);
  39.  
  40.  
  41. int  ignorecfg;
  42.  
  43. static FILE *errorlog;
  44.  
  45.  
  46. /* avoid wild card expansion on the command line (DJGPP feature) */
  47. char **__crt0_glob_function(void)
  48. {
  49.     return 0;
  50. }
  51.  
  52. static void signal_handler(int num)
  53. {
  54.     if (errorlog) fflush(errorlog);
  55.  
  56.     osd_exit();
  57.     allegro_exit();
  58.     ScreenClear();
  59.     ScreenSetCursor( 0, 0 );
  60.     if( num == SIGINT )
  61.         cpu_dump_states();
  62.  
  63.     signal(num, SIG_DFL);
  64.     raise(num);
  65. }
  66.  
  67. /* put here anything you need to do when the program is started. Return 0 if */
  68. /* initialization was successful, nonzero otherwise. */
  69. int osd_init(void)
  70. {
  71.     if (msdos_init_sound())
  72.         return 1;
  73.     msdos_init_input();
  74.     return 0;
  75. }
  76.  
  77.  
  78. /* put here cleanup routines to be executed when the program is terminated. */
  79. void osd_exit(void)
  80. {
  81.     msdos_shutdown_sound();
  82.     msdos_shutdown_input();
  83. }
  84.  
  85. /* fuzzy string compare, compare short string against long string        */
  86. /* e.g. astdel == "Asteroids Deluxe". The return code is the fuzz index, */
  87. /* we simply count the gaps between maching chars.                       */
  88. int fuzzycmp (const char *s, const char *l)
  89. {
  90.     int gaps = 0;
  91.     int match = 0;
  92.     int last = 1;
  93.  
  94.     for (; *s && *l; l++)
  95.     {
  96.         if (*s == *l)
  97.             match = 1;
  98.         else if (*s >= 'a' && *s <= 'z' && (*s - 'a') == (*l - 'A'))
  99.             match = 1;
  100.         else if (*s >= 'A' && *s <= 'Z' && (*s - 'A') == (*l - 'a'))
  101.             match = 1;
  102.         else
  103.             match = 0;
  104.  
  105.         if (match)
  106.             s++;
  107.  
  108.         if (match != last)
  109.         {
  110.             last = match;
  111.             if (!match)
  112.                 gaps++;
  113.         }
  114.     }
  115.  
  116.     /* penalty if short string does not completely fit in */
  117.     for (; *s; s++)
  118.         gaps++;
  119.  
  120.     return gaps;
  121. }
  122.  
  123. int main (int argc, char **argv)
  124. {
  125.     int res, i, j = 0, game_index;
  126.     char *playbackname = NULL;
  127.  
  128.     memset(&options,0,sizeof(options));
  129.  
  130.     /* these two are not available in mame.cfg */
  131.     ignorecfg = 0;
  132.     errorlog = 0;
  133.  
  134.     game_index = -1;
  135.  
  136.     for (i = 1;i < argc;i++) /* V.V_121997 */
  137.     {
  138.         if (stricmp(argv[i],"-ignorecfg") == 0) ignorecfg = 1;
  139.         if (stricmp(argv[i],"-log") == 0)
  140.             errorlog = fopen("error.log","wa");
  141.         if (stricmp(argv[i],"-playback") == 0)
  142.         {
  143.             i++;
  144.             if (i < argc)  /* point to inp file name */
  145.                 playbackname = argv[i];
  146.         }
  147.     }
  148.  
  149.     allegro_init();
  150.  
  151.     /* Allegro changed the signal handlers... change them again to ours, to */
  152.     /* avoid the "Shutting down Allegro" message which confuses users into */
  153.     /* thinking crashes are caused by Allegro. */
  154.     signal(SIGABRT, signal_handler);
  155.     signal(SIGFPE,  signal_handler);
  156.     signal(SIGILL,  signal_handler);
  157.     signal(SIGSEGV, signal_handler);
  158.     signal(SIGTERM, signal_handler);
  159.     signal(SIGINT,  signal_handler);
  160.     signal(SIGKILL, signal_handler);
  161.     signal(SIGQUIT, signal_handler);
  162.  
  163.     #ifdef MESS
  164.     set_config_file ("mess.cfg");
  165.     #else
  166.     set_config_file ("mame.cfg");
  167.     #endif
  168.  
  169.     /* check for frontend options */
  170.     res = frontend_help (argc, argv);
  171.  
  172.     /* if frontend options were used, return to DOS with the error code */
  173.     if (res != 1234)
  174.         exit (res);
  175.  
  176.     /* Initialize the audio library */
  177.     if (msdos_init_seal())
  178.     {
  179.         printf ("Unable to initialize SEAL\n");
  180.         return (1);
  181.     }
  182.  
  183.     init_ticker();    /* after Allegro init because we use cpu_cpuid */
  184.  
  185.     /* handle playback which is not available in mame.cfg */
  186.     init_inpdir(); /* Init input directory for opening .inp for playback */
  187.  
  188.     if (playbackname != NULL)
  189.         options.playback = osd_fopen(playbackname,0,OSD_FILETYPE_INPUTLOG,0);
  190.  
  191.     /* check for game name embedded in .inp header */
  192.     if (options.playback)
  193.     {
  194.         INP_HEADER inp_header;
  195.  
  196.         /* read playback header */
  197.         osd_fread(options.playback, &inp_header, sizeof(INP_HEADER));
  198.  
  199.         if (!isalnum(inp_header.name[0])) /* If first byte is not alpha-numeric */
  200.             osd_fseek(options.playback, 0, SEEK_SET); /* old .inp file - no header */
  201.         else
  202.         {
  203.             for (i = 0; (drivers[i] != 0); i++) /* find game and play it */
  204.             {
  205.                 if (strcmp(drivers[i]->name, inp_header.name) == 0)
  206.                 {
  207.                     game_index = i;
  208.                     printf("Playing back previously recorded game %s (%s) [press return]\n",
  209.                         drivers[game_index]->name,drivers[game_index]->description);
  210.                     getchar();
  211.                     break;
  212.                 }
  213.             }
  214.         }
  215.     }
  216.  
  217.     /* If not playing back a new .inp file */
  218.     if (game_index == -1)
  219.     {
  220.         /* take the first commandline argument without "-" as the game name */
  221.         for (j = 1; j < argc; j++)
  222.         {
  223.             if (argv[j][0] != '-') break;
  224.         }
  225.         /* do we have a driver for this? */
  226. #ifdef MAME_DEBUG
  227.         /* pick a random game */
  228.         if (stricmp(argv[j],"random") == 0)
  229.         {
  230.             struct timeval t;
  231.  
  232.             i = 0;
  233.             while (drivers[i]) i++;    /* count available drivers */
  234.  
  235.             gettimeofday(&t,0);
  236.             srand(t.tv_sec);
  237.             game_index = rand() % i;
  238.  
  239.             printf("Running %s (%s) [press return]\n",drivers[game_index]->name,drivers[game_index]->description);
  240.             getchar();
  241.         }
  242.         else
  243. #endif
  244.         {
  245.             for (i = 0; drivers[i] && (game_index == -1); i++)
  246.             {
  247.                 if (stricmp(argv[j],drivers[i]->name) == 0)
  248.                 {
  249.                     game_index = i;
  250.                     break;
  251.                 }
  252.             }
  253.  
  254.             /* educated guess on what the user wants to play */
  255.             if (game_index == -1)
  256.             {
  257.                 int fuzz = 9999; /* best fuzz factor so far */
  258.  
  259.                 for (i = 0; (drivers[i] != 0); i++)
  260.                 {
  261.                     int tmp;
  262.                     tmp = fuzzycmp(argv[j], drivers[i]->description);
  263.                     /* continue if the fuzz index is worse */
  264.                     if (tmp > fuzz)
  265.                         continue;
  266.  
  267.                     /* on equal fuzz index, we prefer working, original games */
  268.                     if (tmp == fuzz)
  269.                     {
  270.                         /* game is a clone */
  271.                         if (drivers[i]->clone_of != 0
  272.                                 && !(drivers[i]->clone_of->flags & NOT_A_DRIVER))
  273.                         {
  274.                             /* if the game we already found works, why bother. */
  275.                             /* and broken clones aren't very helpful either */
  276.                             if ((!drivers[game_index]->flags & GAME_NOT_WORKING) ||
  277.                                 (drivers[i]->flags & GAME_NOT_WORKING))
  278.                                 continue;
  279.                         }
  280.                         else continue;
  281.                     }
  282.  
  283.                     /* we found a better match */
  284.                     game_index = i;
  285.                     fuzz = tmp;
  286.                 }
  287.  
  288.                 if (game_index != -1)
  289.                     printf("fuzzy name compare, running %s\n",drivers[game_index]->name);
  290.             }
  291.         }
  292.  
  293.         if (game_index == -1)
  294.         {
  295.             printf("Game \"%s\" not supported\n", argv[j]);
  296.             return 1;
  297.         }
  298.     }
  299.  
  300.     #ifdef MESS
  301.     /* This function has been added to MESS.C as load_image() */
  302.     load_image(argc, argv, j, game_index);
  303.     #endif
  304.  
  305.     /* parse generic (os-independent) options */
  306.     parse_cmdline (argc, argv, game_index);
  307.  
  308. {    /* Mish:  I need sample rate initialised _before_ rom loading for optional rom regions */
  309.     extern int soundcard;
  310.  
  311.     if (soundcard == 0) {    /* silence, this would be -1 if unknown in which case all roms are loaded */
  312.         Machine->sample_rate = 0; /* update the Machine structure to show that sound is disabled */
  313.         options.samplerate=0;
  314.     }
  315. }
  316.  
  317.     /* handle record which is not available in mame.cfg */
  318.     for (i = 1; i < argc; i++)
  319.     {
  320.         if (stricmp(argv[i],"-record") == 0)
  321.         {
  322.             i++;
  323.             if (i < argc)
  324.                 options.record = osd_fopen(argv[i],0,OSD_FILETYPE_INPUTLOG,1);
  325.         }
  326.     }
  327.  
  328.     if (options.record)
  329.     {
  330.         INP_HEADER inp_header;
  331.  
  332.         memset(&inp_header, '\0', sizeof(INP_HEADER));
  333.         strcpy(inp_header.name, drivers[game_index]->name);
  334.         /* MAME32 stores the MAME version numbers at bytes 9 - 11
  335.          * MAME DOS keeps this information in a string, the
  336.          * Windows code defines them in the Makefile.
  337.          */
  338.         /*
  339.         inp_header.version[0] = 0;
  340.         inp_header.version[1] = VERSION;
  341.         inp_header.version[2] = BETA_VERSION;
  342.         */
  343.         osd_fwrite(options.record, &inp_header, sizeof(INP_HEADER));
  344.     }
  345.  
  346.     #ifdef MESS
  347.     /* Build the CRC database filename */
  348.     sprintf(crcfilename, "%s/%s.crc", crcdir, drivers[game_index]->name);
  349.     if (drivers[game_index]->clone_of->name)
  350.         sprintf (pcrcfilename, "%s/%s.crc", crcdir, drivers[game_index]->clone_of->name);
  351.     else
  352.         pcrcfilename[0] = 0;
  353.     #endif
  354.  
  355.     /* go for it */
  356.     res = run_game (game_index);
  357.  
  358.     /* close open files */
  359.     if (errorlog) fclose (errorlog);
  360.     if (options.playback) osd_fclose (options.playback);
  361.     if (options.record)   osd_fclose (options.record);
  362.     if (options.language_file) osd_fclose (options.language_file);
  363.  
  364.     exit (res);
  365. }
  366.  
  367.  
  368.  
  369. void CLIB_DECL logerror(const char *text,...)
  370. {
  371.     va_list arg;
  372.     va_start(arg,text);
  373.     if (errorlog)
  374.         vfprintf(errorlog,text,arg);
  375.     va_end(arg);
  376. }
  377.